package com.maychat.utils;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.maychat.config.Consts;
import com.maychat.enums.ContactType;
import com.maychat.pojo.MayChatSystemOptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;

@Slf4j
public class StringTools {

    public static final String DOT = "\\.";
    public static final String EMPTY = "";

    public static String cryptoMD5(String password) {
        return password == null ? null : DigestUtils.md5Hex(password);
    }

    public static int compareVersions(String v1, String v2) {
        if (v1 == null || v2 == null) return 0;
        String[] v1s = v1.split(DOT);
        String[] v2s = v2.split(DOT);
        int min = Math.min(v1s.length, v2s.length);
        for (int i = 0; i < min; i++) {
            if (v1s[i].equals(v2s[i])) continue;
            return v1s[i].compareTo(v2s[i]);
        }
        return v1s.length - v2s.length;
    }

    public static String generateSessionId(String... ids) {
        Arrays.sort(ids);
        String concat = Arrays.stream(ids).reduce((a, b) -> a + b).get();
        return cryptoMD5(concat);
    }

    public static String generateGroupSessionId(String id) {
        return cryptoMD5(id);
    }

    public static String escapeHTML(String html) {
        if (html == null) return null;
        return StringEscapeUtils.escapeHtml4(html);
    }

    public static String generateRandomUserId() {
        return ContactType.USER.getPrefix() + RandomStringUtils.randomNumeric(11);
    }

    public static String generateRandomGroupId() {
        return ContactType.GROUP.getPrefix() + RandomStringUtils.randomNumeric(11);
    }

    public static <T> String stringify(T obj) {
        return JSON.toJSONString(obj, JSONWriter.Feature.WriteNulls, JSONWriter.Feature.PrettyFormat);
    }

    /**
     * 这个函数会检测对应的文件类型是否符合对应的大小要求，符合则返回对应的后缀名(没有后缀名返回空字符串)，不符合要求直接返回null
     *
     * @return 返回null或文件后缀名（后缀名含.）
     */
    public static String getExtNameWithCheck(String fileName, Long fileSize, MayChatSystemOptions options) {
        String extName = getExtName(fileName);
        boolean ok;
        if (Consts.IMAGE_EXTS.contains(extName))
            ok = fileSize <= options.getMaxImageSize() * Consts.BYTES_PER_MB;
        else if (Consts.VIDEO_EXTS.contains(extName))
            ok = fileSize <= options.getMaxVideoSize() * Consts.BYTES_PER_MB;
        else
            ok = fileSize <= options.getMaxFileSize() * Consts.BYTES_PER_MB;
        return ok ? extName : null;
    }

    public static String getExtName(String fileName) {
        int i = fileName.lastIndexOf('.');
        if (i < 1) return EMPTY;
        return fileName.substring(i);
    }

    public static String getMimeType(String extName) {
        if (Consts.IMAGE_EXTS.contains(extName)) return Consts.IMAGE_MIME;
        else if (Consts.VIDEO_EXTS.contains(extName)) return Consts.VIDEO_MIME;
        return Consts.DEFAULT_MIME;
    }

    public static String getYearMonth(LocalDateTime localDateTime) {
        int year = localDateTime.getYear();
        int month = localDateTime.getMonthValue();
        String monthStr = StringUtils.leftPad(String.valueOf(month), 2, '0');
        return year + monthStr;
    }

    public static String getYearMonth(Long timeStamp) {
        Instant instant = Instant.ofEpochMilli(timeStamp);
        ZoneId zoneId = ZoneId.systemDefault(); // 使用系统默认时区
        return getYearMonth(LocalDateTime.ofInstant(instant, zoneId));
    }

    public static boolean isNumber(String id) {
        return id.matches("^[0-9]+$");
    }

}
